package com.dctp.ems.controller;

import com.dctp.common.cache.FuturesCache;
import com.dctp.common.controller.BaseController;
import com.dctp.common.utils.CollectUtil;
import com.dctp.common.utils.DateUtil;
import com.dctp.common.vo.JsonResult;
import com.dctp.common.vo.PageResult;
import com.jfinal.aop.Before;
import com.jfinal.core.Path;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 期货品种管理
 * basePath: /futures
 */
@Path("/futures")
public class FuturesController extends BaseController {

    /**
     * GET /futures/list
     * <p>分页查询期货品种，返回exchange_name</p>
     */
    public void list() {
        int page = getInt("currentPage", 1);
        int pageSize = getInt("pageSize", 10);
        String code = getPara("code", "");
        String name = getPara("name", "");
        Integer exchangeId = getParaToInt("exchange_id");
        String status = getPara("status", "");

        StringBuilder where = new StringBuilder(" WHERE f.deleted = 0 ");
        List<Object> params = new ArrayList<>();
        if (StrKit.notBlank(code)) {
            where.append(" AND f.code LIKE ? ");
            params.add('%' + code + '%');
        }
        if (StrKit.notBlank(name)) {
            where.append(" AND f.name LIKE ? ");
            params.add('%' + name + '%');
        }
        if (exchangeId != null) {
            where.append(" AND f.exchange_id = ? ");
            params.add(exchangeId);
        }
        if (StrKit.notBlank(status)) {
            where.append(" AND f.status = ? ");
            params.add(status);
        }

        String select = "SELECT f.*, e.name AS exchange_name ";
        String from = "FROM dctp_futures f LEFT JOIN dctp_exchange e ON f.exchange_id = e.id" + where + " ORDER BY f.display_order ASC, f.id ASC";
        var p = Db.paginate(page, pageSize, select, from, params.toArray());
        renderJson(JsonResult.successWithData(
            new PageResult<>(p.getList(), p.getTotalRow(), pageSize, page)
        ));
    }

    /**
     * POST /futures/add
     * <p>添加期货品种</p>
     */
    @Before(Tx.class)
    public void add() {
        Record body = jsonBody();
        if (StrKit.isBlank(body.getStr("code")) || StrKit.isBlank(body.getStr("name"))) {
            renderJson(JsonResult.failWithMessage("品种编码和名称不能为空"));
            return;
        }
        // 计算每点价值
        Number multiplier = body.getNumber("contract_multiplier");
        Number tickSize = body.getNumber("tick_size");
        if (multiplier != null && tickSize != null) {
            body.set("tick_value", multiplier.doubleValue() * tickSize.doubleValue());
        }
        // 检查唯一
        Long exist = Db.queryLong("SELECT id FROM dctp_futures WHERE code=? AND deleted=0", body.getStr("code"));
        if (exist != null) {
            renderJson(JsonResult.failWithMessage("品种编码已存在"));
            return;
        }
        body.set("create_time", DateUtil.now())
            .set("deleted", 0);
        if (!Db.save("dctp_futures", body)) {
            throw new RuntimeException("新增期货品种失败");
        }
 
        renderJson(JsonResult.success());
    }

    /**
     * POST /futures/update/:id
     * <p>更新期货品种</p>
     */
    @Before(Tx.class)
    public void update() {
        Integer id = getParaToInt(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        Record body = jsonBody();
        if (body.getColumns().isEmpty()) {
            renderJson(JsonResult.failWithMessage("无有效字段"));
            return;
        }
        // 计算每点价值
        Number multiplier = body.getNumber("contract_multiplier");
        Number tickSize = body.getNumber("tick_size");
        if (multiplier != null && tickSize != null) {
            body.set("tick_value", multiplier.doubleValue() * tickSize.doubleValue());
        }
        // 检查 code 唯一（如果修改了code）
        String newCode = body.getStr("code");
        if (StrKit.notBlank(newCode)) {
            Record old = Db.findById("dctp_futures", id);
            if (old == null || old.getInt("deleted") == 1) {
                renderJson(JsonResult.failWithMessage("记录不存在"));
                return;
            }
            if (!newCode.equals(old.getStr("code"))) {
                Long exist = Db.queryLong("SELECT id FROM dctp_futures WHERE code=? AND id<>? AND deleted=0", newCode, id);
                if (exist != null) {
                    renderJson(JsonResult.failWithMessage("品种编码已存在"));
                    return;
                }
            }
        }
        body.set("id", id)
            .set("update_time", DateUtil.now());
        boolean updated = Db.update("dctp_futures", body);
        if (!updated) {
            renderJson(JsonResult.failWithMessage("更新失败或记录不存在"));
            return;
        }

        //删除缓存
        try {
            FuturesCache.delete(id.longValue());
        }catch (Exception e){

        }
        renderJson(JsonResult.success());
    }

    /**
     * POST /futures/delete/:id
     * <p>逻辑删除期货品种</p>
     */
    @Before(Tx.class)
    public void delete() {
        Integer id = getParaToInt(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        int r = Db.update("UPDATE dctp_futures SET deleted=1, update_time=? WHERE id=? AND deleted=0", DateUtil.now(), id);
        if (r == 0) {
            renderJson(JsonResult.failWithMessage("删除失败或记录不存在"));
        } else {
            renderJson(JsonResult.success());
        }
    }

    /**
     * GET /futures/all
     * <p>获取所有启用状态的期货品种</p>
     */
    public void all() {
        List<Record> list = Db.find("SELECT id, code, name FROM dctp_futures WHERE status = 1 AND deleted=0 ORDER BY display_order ASC, id ASC");
        renderJson(JsonResult.successWithData(list));
    }

    /**
     * GET /futures/tradeTimeList
     * 获取某品种的所有交易时间段
     */
    public void tradeTimeList() {
        Long futuresId = getParaToLong("futures_id");
        if (futuresId == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        List<Record> list = Db.find("SELECT id, begin_time, end_time,seq FROM dctp_futures_trade_time WHERE futures_id = ? ORDER BY seq ASC", futuresId);
        renderJson(JsonResult.successWithData(CollectUtil.convert(list, Record::getColumns)));
    }

    /**
     * POST /futures/setTradeTime/:futures_id
     * 设置某品种的交易时间段（先删后插）
     */
    @Before(Tx.class)
    public void setTradeTime() {
        Long futuresId = getParaToLong(0);
        if (futuresId == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        List<Record> segments = jsonArrayBody();
        // 校验：开始时间不能大于结束时间
        for (Record seg : segments) {
            String begin = seg.getStr("begin_time");
            String end = seg.getStr("end_time");
            if (begin != null && end != null) {
                LocalTime beginTime = LocalTime.parse(begin);
                LocalTime endTime = LocalTime.parse(end);
                if (beginTime.isAfter(endTime)) {
                    renderJson(JsonResult.failWithMessage("开始时间不能大于结束时间"));
                    return;
                }
            }
        }
        // 删除原有
        Db.update("DELETE FROM dctp_futures_trade_time WHERE futures_id = ?", futuresId);
        Db.update(" DELETE FROM  dctp_liquidation_rule where futures_id = ? ",futuresId);
        // 批量插入
        for (Record seg : segments) {
            seg.set("futures_id", futuresId);
            Db.save("dctp_futures_trade_time", seg);
            Record rule = new Record()
                .set("futures_id", futuresId)
                .set("trade_time_id", seg.getLong("id"))
                .set("status", 0) // 默认启用
                .set("create_time", DateUtil.now())
                .set("update_time", DateUtil.now());
            Db.save("dctp_liquidation_rule", rule);
        }
        renderJson(JsonResult.success());
    }
}
